﻿using SimpleCrawler.DAL;
using SimpleCrawler.DependencyInjection;
using SimpleCrawler.Entity;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using System.Threading;

namespace SimpleCrawler.Crawler
{
    public class BaiDuWDCrawler : CrawlerBase
    {    
        //private ILog logger;    
        CrawlerDAL dal;
        public BaiDuWDCrawler():base(1008,"百度问答") {
            //logger = LoggerManager.GetLogger(GetType());
            dal = AppServiceProvider.ServiceProvider.GetService<CrawlerDAL>();
        }

        public override void GetStartedPageUrl()
        {  
            RequestUrl = $"https://zhidao.baidu.com/search?word={System.Web.HttpUtility.UrlEncode(CrawlerTask.KeyWord)}&site=-1&sites=0&date=3&pn=0";
        }
        public override void GetNextPageUrl(int page)
        {
            RequestUrl = $"https://zhidao.baidu.com/search?word={System.Web.HttpUtility.UrlEncode(CrawlerTask.KeyWord)}&site=-1&sites=0&date=3&pn={page-1}0";
        }

        public override async Task<string> GetTargetHtmlString()
        {
            return await base.SendRequestByGet(RequestUrl,null,false, "GB2312");
        }

        public async override Task<int> GetResultContent(string html)
        {
            Match table = Regex.Match(html, @"class=""list-inner"">[\s\S]*?<div class=""list-footer"">");
            MatchCollection trlist = Regex.Matches(table.ToString(), @"<dl [\s\S]*?</dl>");
            Regex realUrlReg = new Regex(@"<a href=""([\s\S]*?)""[\s\S]*?>([\s\S]*?)</a>[\s\S]*?<span class=""mr-8"">(\d{4}-\d{1,2}-\d{1,2})</span>");

            //Regex quetionReg = new Regex(@"id=""v-times""[\s\S]*?> 浏览 (\d*) 次</span>");
            Regex bestAnswer = new Regex(@"id=""best-answer-[\s\S]*?answer-time[\s\S]*?(\d{4}-\d{1,2}-\d{1,2})[\s\S]*?id=""best-content-[\s\S]*?>([\s\S]*?)</pre>");

            Regex otherAnswers = new Regex(@"id=""wgt-answers""[\s\S]*?wgt-bottom-union mod-shadow");
            Regex otherAnswer = new Regex(@"<div class=""bd answer[\s\S]*?answer-text line[\s\S]*?>([\s\S]*?)</div>[\s\S]*?pos-time[\s\S]*?(\d{4}-\d{1,2}-\d{1,2})\s*?</span>");

            List<WD_Question> questions = new List<WD_Question>();
            if (trlist.Count > 0)
            {
                foreach (var tr in trlist)
                {
                    Match MrealUrl = realUrlReg.Match(tr.ToString());
                    if (MrealUrl.Success)
                    {
                        WD_Question question = new WD_Question();
                        string url = MrealUrl.Groups[1].ToString().Trim();
                        //url过滤
                        if (Filter != null && Filter.Contains(url))
                        {
                            Logger.Error($"已过滤的问答,link=>{url}");
                            FilterCount++;
                            continue;
                        }
                        Filter.Add(url);
                        //
                        string detailHtml = await SendRequestByGet(url, null, false, "GB2312");
                        Thread.Sleep(10 * 1000);
                        try
                        {
                            question.SourceSite = this.CrawlerID;
                            question.KeyWord = this.CrawlerTask.KeyWord;
                            question.SourceUrl = url;
                            question.Question = CleanTag(MrealUrl.Groups[2].ToString()).Replace("\"", "");
                            question.CreateTime = DateTime.Parse(MrealUrl.Groups[3].ToString());
                        }
                        catch (Exception ex)
                        {
                            Logger.Error($"问题匹配出错,link=>{url} {ex.ToString()}");
                        }
                        if (string.IsNullOrEmpty(question.Question) || question.CreateTime == null)
                            continue;

                        question.Answers = new List<WD_Answer>();
                        Match MbestAnswer = bestAnswer.Match(detailHtml);
                        if (MbestAnswer.Success)
                        {
                            WD_Answer answer = new WD_Answer();
                            try
                            {
                                answer.IsAdopt = 1;
                                answer.Answer = MbestAnswer.Groups[2].ToString();
                                answer.AnswerLen = answer.Answer.Length;
                                answer.CreateDate = DateTime.Parse(MbestAnswer.Groups[1].ToString());
                            }
                            catch (Exception ex)
                            {
                                Logger.Error($"最佳答案匹配出错,link=>{url} {ex.ToString()}");
                            }
                            if (!string.IsNullOrEmpty(answer.Answer))
                            {
                                question.Answers.Add(answer);
                            }
                        }

                        MatchCollection MotherAnswers = otherAnswer.Matches(otherAnswers.Match(detailHtml).ToString());
                        foreach (Match item in MotherAnswers)
                        {
                            WD_Answer answer = new WD_Answer();
                            try
                            {
                                answer.Answer = item.Groups[1].ToString();
                                answer.AnswerLen = answer.Answer.Length;
                                answer.CreateDate = DateTime.Parse(item.Groups[2].ToString());
                            }
                            catch (Exception ex)
                            {
                                Logger.Error($"其他答案匹配出错,link=>{url} {ex.ToString()}");
                            }
                            if (!string.IsNullOrEmpty(answer.Answer))
                            {
                                question.Answers.Add(answer);
                            }
                        }
                        questions.Add(question);
                        if (question.Answers.Count == 0)
                            Logger.Error($"未匹配到答案,link=>{url}");
                    }
                    else
                    {
                        Logger.Error($"问题匹配出错,link=>{RequestUrl}");
                        continue;
                    }
                }
            }

            if (FilterCount > 0 && trlist.Count == FilterCount)
            {
                FilterCount = 0;
                return -1;
            }
            FilterCount = 0;
            if (questions.Count > 0)
            {
                var result = await SaveToDB(questions);
                Match next = Regex.Match(html, @"class=""pager-next""[\s\S]*?>下一页");
                if (next.Success)
                {
                    CrawlerTask.EndPage = CrawlerTask.StartPage + 1;
                }
                if (!string.IsNullOrEmpty(result.Content))
                {
                    Logger.Error(result.Content);
                }
                return result.Count;
            }
            return 0;
        }

        protected async Task<(int Count, string Content)> SaveToDB(List<WD_Question> list)
        {
            return await dal.AddQuestions(list).ConfigureAwait(continueOnCapturedContext: false);
        }
    }
}
